package com.tender.integration.config.filter;

import com.tender.integration.config.properties.MsgProperties;
import com.tender.utils.ApplicationContextUtil;
import com.tender.service.TokenService;
import com.tender.utils.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
@WebFilter(filterName = "truckGlobalFilter", urlPatterns = "/*")
public class GlobalOnceRequestFilter extends OncePerRequestFilter {

    private volatile TokenService tokenService;

    private volatile MsgProperties msgProperties;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String uuid = UUID.randomUUID().toString();

        long start = System.currentTimeMillis();
        try {
            String uri = request.getRequestURI();
            // StringBuffer url = request.getRequestURL();
            String method = request.getMethod();
            log.info("=============> uuid：{}, start：{}", uuid, start);
            log.info("=============> uuid：{}, method：{}, uri：{}", uuid, method, uri);
            // 在白名单中（比如：登录（测试使用），获取 host 信息，获取favicon.ico 等）
            List<String> filterUris = Arrays.stream(getMsgProperties().getWhiteUrls()).
                    filter(uri::contains).collect(Collectors.toList());
            // 不在白名单中的，需要解析 token
            if (CollectionUtils.isEmpty(filterUris)) {
                UserProvider.setUserInfo(getTokenService().parse());
            }

            filterChain.doFilter(request, response);
        } finally {
            log.info("=============> uuid：{}, cost：{}", uuid, (System.currentTimeMillis() - start) / 1000);
            UserProvider.clear();
        }
    }

    /**
     * 单例模式
     */
    private TokenService getTokenService() {
        if (null == tokenService) {
            synchronized (GlobalOnceRequestFilter.class) {
                if (null == tokenService) {
                    return ApplicationContextUtil.getBean(TokenService.class);
                }
            }
        }

        return tokenService;
    }

    private MsgProperties getMsgProperties() {
        if (null == msgProperties) {
            synchronized (GlobalOnceRequestFilter.class) {
                if (null == msgProperties) {
                    return ApplicationContextUtil.getBean(MsgProperties.class);
                }
            }
        }

        return msgProperties;
    }

}
